package ig.metrica.riesgo;

import ig.metrica.TasaFactorDescuento;
import java.rmi.RemoteException;
import java.sql.PreparedStatement;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Date;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.Properties;
import javax.ejb.FinderException;
import javax.naming.Context;
import javax.naming.InitialContext;
import javax.naming.NamingException;
import ig.finanzas.Banda;
import ig.finanzas.ContratoPK;
import ig.finanzas.ContratoSimple;
import ig.finanzas.ContratoSimpleHome;
import ig.finanzas.EspeciePK;
import ig.finanzas.Flujo;
import ig.finanzas.ManejadorBandas;
import ig.finanzas.ManejadorFlujos;
import ig.finanzas.Moneda;
import ig.finanzas.MonedaHome;
import ig.finanzas.MonedaPK;
import ig.finanzas.PosicionAccion;
import ig.finanzas.PosicionAccionHome;
import ig.finanzas.PosicionEspecie;
import ig.finanzas.PosicionEspecieHome;
import ig.finanzas.ProductoPK;
import ig.finanzas.Tasa;
import ig.finanzas.TasaHome;
import ig.finanzas.TasaPK;
import ig.finanzas.riesgo.FactorRiesgoPersonal;
import ig.metrica.ejb.bean.Productos;
import ig.metrica.ejb.html.GenerarHTML;
import ig.util.ConexionServer;
import ig.util.ejb.IGLlaveInt;
import ig.util.ejb.IGSessionBean;
import ig.util.excepciones.DatoInvalidoExcepcion;
import ig.util.excepciones.LogicaExcepcion;
import java.util.ArrayList;

public class CalculoRiesgoBeanEscBan extends IGSessionBean implements CalculoRiesgoBussines {

    private GenerarHTML generarHTML = null;
    private Properties prop = null;
    private Hashtable cambioesperadoMonedas = new Hashtable();
    private MonedaHome monedaHome = null;
    private InitialContext _ctx = null;
    private TasaHome tasaHome = null;
    private Collection<ZonaDTO> collection = new ArrayList();
    private Hashtable<String, Integer> errores = new Hashtable<String, Integer>();
    private boolean fechaInicioCerrada = false;

    public CalculoRiesgoBeanEscBan() {
    }
    

    {
        prop = new Properties();
        prop.put(Context.INITIAL_CONTEXT_FACTORY, INITIAL_CONTEXT_FACTORY);
        String Sockec = new ConexionServer().getSocketServer();
        prop.put(Context.PROVIDER_URL, Sockec);
    }

    public void setGenerarHTML(GenerarHTML generarHTML) {
        this.generarHTML = generarHTML;
    }

    public void ejbCreate() {
    }

    private Moneda getMoneda(MonedaPK monedaPK) throws NamingException, FinderException {
        if (_ctx != null) {
            _ctx.close();
        }
        _ctx = new InitialContext(prop);
        try {
            if (monedaHome == null) {
                monedaHome = (MonedaHome) _ctx.lookup("ig.finanzas.Moneda");
            }
            return monedaHome.findByPrimaryKey(monedaPK);
        } catch (RemoteException e) {
            System.out.println("ERROR:" + e.toString());
        }
        return null;

    }

    private Tasa getTasa(TasaPK tasaPK) throws NamingException, FinderException {
        try {
            if (_ctx != null) {
                _ctx.close();
            }
            _ctx = new InitialContext(prop);
            if (tasaHome == null) {
                tasaHome = (TasaHome) _ctx.lookup("ig.finanzas.Tasa");
            }
            return tasaHome.findByPrimaryKey(tasaPK);
        } catch (RemoteException e) {
            System.out.println("ERROR:" + e.toString());
        }
        return null;
    }

    /**
     *
     * @param fecha
     * @param confPeriodos
     * @param numdias
     * @param relacionProductosFactores
     * @param relacionEspeciesFactores
     * @param relacionMonedasFactores
     * @throws DatoInvalidoExcepcion Si alguno de los parametros del metodo es nulo,
     * o si se especifico un factor tipo tasa para las acciones o uno tipo precio para los contratos simples.
     * o si alguno de los datos de la configuracion de los periodos de una banda es 0,
     * o si un dato es menor a su inmediatamente anterior.
     * @throws LogicaExcepcion Si no se definio Factor de Riesgo para algun producto, alguna especie o
     * para alguna moneda, si alguna de las formas de calculo del cambio esperado no permite obtener el valor, si no hay suficientes
     * valores en la serie, si la informacion hallada no alcanza a ser una muestra estadisticamente representativa,
     * o si la serie no permite el calculo utilizando diferencias logaritmicas.
     * O si al querer calcular el var de un contrato usando tasas este no tiene flujos para efectuar la operacion.
     * @throws NamingException Si se presento un error con JNDI.
     * @throws SQLException Si no se pueden encontrar los objetos en el servidor de aplicaciones.
     * @throws FinderException Si no se pueden encontrar los objetos en el servidor de aplicaciones.
     */
    public void efectuarCalculo(
            Date fecha,
            ManejadorBandas bandas,
            Hashtable relacionProductosFactores,
            Hashtable relacionEspeciesFactores,
            Hashtable relacionMonedasFactores) throws DatoInvalidoExcepcion, LogicaExcepcion, NamingException, SQLException, FinderException {
        errores = new Hashtable<String, Integer>();
        if (fecha == null) {
            generarHTML.println("La fecha especificada es nula.");
            throw new DatoInvalidoExcepcion("La fecha especificada es nula.");
        }

        if (relacionProductosFactores == null && relacionEspeciesFactores == null) {
            generarHTML.println("La relacion entre especies/productos y factores de riesgo es nula.");
            throw new DatoInvalidoExcepcion("La relacion entre especies y factores de riesgo es nula.");
        }

        if (relacionMonedasFactores == null) {
            generarHTML.println("La relacion entre monedas y factores de reisgo es nula.");
            throw new DatoInvalidoExcepcion("La relacion entre monedas y factores de reisgo es nula.");
        }

        cambioesperadoMonedas = new Hashtable();
        PreparedStatement pstmt4_ = null;
        Productos productos = null;

        try {
            conn = getConexion("METRICADB");
            Collection contratos;
            Iterator i, j;
            //Los resultados se guardaran en las siguientes tablas.
            pstmt1 = conn.prepareStatement("INSERT INTO VARCONTRATOSPRECIO(IDCONTRATO, VER, FACTORRIESGO, CAMBIOESPERADO) VALUES(?, ?, ?, ?)");

            pstmt2 = conn.prepareStatement("INSERT INTO VARCONTRATOSTASA(IDCONTRATO, VALORPRESENTE, DURACION, TIR, CAMBIOESPERADO, VER, FACTORRIESGO, IDBANDA) VALUES(?, ?, ?, ?, ?, ?, ?, ?)");

            pstmt3 = conn.prepareStatement("INSERT INTO CAMBIOESPERADOMONEDAS VALUES(?, ?)");

            _ctx = new InitialContext(prop);


            /*
             * --------------------------------- POSICIONES ACCIONES  -------------------------------------------------------------
             * Para el caso de contratos de posiciones de acciones la unica manera de calcular el var
             * es multiplicando el numero de unidades por el posible cambio esperado en el precio.
             */

            PosicionAccionHome home3 = (PosicionAccionHome) _ctx.lookup("ig.finanzas.PosicionAccion");
            contratos = home3.findAll();
            i = contratos.iterator();
            generarHTML.println("Procesando :" + contratos.size() + " Valores contrato");
            while (i.hasNext()) {

                //Recorriendo las posiciones
                PosicionAccion posicion = (PosicionAccion) i.next();
                ProductoPK productoPK = posicion.getProductoPK();

                //Determino el factor de riesgo especificado por el usuario para el producto
                if (!relacionProductosFactores.containsKey(productoPK)) {
                    generarHTML.println("Falta definir el factor de riesgo para el producto " + productoPK);
                    throw new LogicaExcepcion("Falta definir el factor de riesgo para el producto " + productoPK);
                }
                FactorRiesgoPersonalMetrica factor = (FactorRiesgoPersonalMetrica) relacionProductosFactores.get(productoPK);
                if (factor == null) {
                    generarHTML.println("Falta definir el factor de riesgo para el producto " + productoPK);
                }

                //Determinando el valor en riesgo
                double var = posicion.valorEnRiesgo(fecha, factor, true);
                String factorMatriz = factor.getFactorRiesgoMatrizCorrelacion().getNombre();
                Double cambioesperado = 0D;
                if (factor.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                    cambioesperado = factor.getFactorRiesgoMatrizCorrelacion().getCambioEsperado();
                } else {
                    try {
                        cambioesperado = posicion.cambioEsperadoValoresRegistrados(fecha, factor.getDefinidorCalculoCambioEsperado(), true);
                    } catch (Exception e) {
                        cambioesperado = null;
                        generarHTML.println(" Factor :" + factor.getFactorRiesgoMatrizCorrelacion().getNombre());
                        generarHTML.println(" Posiciones Acciones:" + e.toString());
                    }
                }
                if (cambioesperado != null) {
                    pstmt1.setLong(1, ((ContratoPK) posicion.getPrimaryKey()).getIdInterna());
                    pstmt1.setDouble(2, var);
                    pstmt1.setString(3, factorMatriz);
                    pstmt1.setDouble(4, cambioesperado);                    
                    pstmt1.executeUpdate();
                }
                //Determinando el riesgo de tasa de cambio
                Moneda moneda = getMoneda(posicion.getMonedaPK());
                MonedaPK monedaPK = (MonedaPK) moneda.getPrimaryKey();
                if (!cambioesperadoMonedas.containsKey(monedaPK)) {
                    if (!relacionMonedasFactores.containsKey(monedaPK)) {
                        throw new LogicaExcepcion("Falta definir el factor de riesgo para la moneda " + monedaPK);
                    }
                    FactorRiesgoPersonalMetrica factorMoneda = (FactorRiesgoPersonalMetrica) relacionMonedasFactores.get(monedaPK);
                    Double cambioesperadoMoneda = 0D;
                    Double ValorMonedaVigente = moneda.obtenerValorVigenteA(fecha);
                    if (factorMoneda.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                        cambioesperadoMoneda = factorMoneda.getFactorRiesgoMatrizCorrelacion().getCambioEsperado() * ValorMonedaVigente;
                    } else {
                        try {
                            cambioesperadoMoneda = moneda.cambioEsperadoValoresRegistrados(fecha, factorMoneda.getDefinidorCalculoCambioEsperado());
                            cambioesperadoMoneda = cambioesperadoMoneda * ValorMonedaVigente;
                        } catch (Exception e) {
                            cambioesperadoMoneda = null;
                            generarHTML.println(" Factor :" + factorMoneda.getFactorRiesgoMatrizCorrelacion().getNombre());
                            generarHTML.println(" Moneda:" + e.toString());
                        }
                    }
                    if (cambioesperadoMoneda != null) {
                        cambioesperadoMonedas.put(monedaPK, new Double(cambioesperadoMoneda));
                    }
                }
//                moneda.unsetEntityContext();
//                posicion.unsetEntityContext();
            }

            //----------------------------------------  BANDAS RELACIONADAS AL MODELO --------------------------------------
            //Se crean las bandas

            //ManejadorBandas bandas = ManejadorBandas.crearBandas(fecha, confPeriodos);
            int ahora = bandas.getColeccionBandas().size();
            if (ahora != 0) {
                generarHTML.println("Procesando :" + ahora + " Bandas");
            }
            pstmt4_ = conn.prepareStatement("INSERT INTO BANDASVAR(ID, FECHAINICIO, FECHAFIN) VALUES(?, ?, ?)");
            int contador = 0;
            i = bandas.getColeccionBandas().iterator();
            while (i.hasNext()) {
                Banda banda = (Banda) i.next();
                contador++;
                pstmt4_.setInt(1, contador);
                pstmt4_.setDate(2, new java.sql.Date(banda.getFechaInicio().getTime()));
                if (banda.getFechaFin() != null) {
                    pstmt4_.setDate(3, new java.sql.Date(banda.getFechaFin().getTime()));
                } else {
                    pstmt4_.setDate(3, null);
                }                
                pstmt4_.executeUpdate();
                banda.setIdInterna(contador);
            }

            /***************************************************************************************************
             * Para el caso de contratos simples la unica manera de calcular el var es aplicando
             * la formula que involucra la duracion.
             ***************************************************************************************************/
            _ctx = new InitialContext(prop);
            ContratoSimpleHome home1 = (ContratoSimpleHome) _ctx.lookup("ig.finanzas.ContratoSimple");
            contratos = home1.findAll();
            i = contratos.iterator();
            productos = new Productos();
            generarHTML.println("Procesando :" + contratos.size() + " Contrato en ContratoSimple");
            while (i.hasNext()) {
                try {
                    ContratoSimple contrato = (ContratoSimple) i.next();
                    ProductoPK productoPK = productos.getProductoPK(Long.parseLong(contrato.getPrimaryKey().toString()));

                    if (productoPK != null) {
                        ManejadorFlujos flujosduracion = contrato.flujosParaDuracion(fecha);
                        if (!relacionProductosFactores.containsKey(productoPK)) {
                            throw new LogicaExcepcion("Falta definir el factor de riesgo para el producto " + productoPK);
                        }
                        FactorRiesgoPersonalMetrica factor = (FactorRiesgoPersonalMetrica) relacionProductosFactores.get(productoPK);
                        TasaPK tasaPK = factor.getTasaPK();

                        if (tasaPK == null) {
                            throw new DatoInvalidoExcepcion("El factor de riesgo asociado al producto no es del tipo tasa");
                        }

                        //-----------------------------NUEVA IMPLEMENTACION--------------------

                        String factorMatriz = factor.getFactorRiesgoMatrizCorrelacion().getNombre();
                        Tasa tasa = null;
                        if (tasaPK.getNombre() != null && tasaPK.getNombre().trim().equals("TIPO_FACTORTASA_DESCUENTO")) {
                            tasa = new TasaFactorDescuento("TIPO_FACTORTASA_DESCUENTO", "CONTRATOSSIMPLES", ((IGLlaveInt)contrato.getPrimaryKey()).getIdInterna(), true);
                        } else {
                            tasa = getTasa(tasaPK);
                        }
                        //---------------------------------------------------
                        double cambioesperadoTasa = 0;

                        ManejadorFlujos flujosintervalo = flujosduracion.flujosEntre(fecha, isFechaInicioCerrada(), new Date(new Long("9999999999999")), true);
                        double valorpresente = flujosintervalo.valorDescontado(tasa, fecha);
                        double duracion = flujosintervalo.duracion(fecha, tasa);
                        flujosintervalo.adicionarFlujo(new Flujo(fecha, valorpresente * -1, 0, 0, false, false));
                        double tir = flujosintervalo.tir();

//                        System.out.println("Contrato:" + contrato.getPrimaryKey().toString() + " -> Tir:" + tir);
//                        System.out.println("Math.pow:" + tir);

                        Double duracionModificada = duracion / (1 + tir);

                        //---------- NUEVA IMPLEMENTACION --------------------
                        Integer IDBanda = null;
                        for (ZonaDTO Z : this.collection) {
                            for (BandasDTO B : Z.getBandas()) {
                                if (duracionModificada == 0 && B.getNumero().equals(1)) {
                                    IDBanda = B.getId();
                                    break;
                                }
                                if (duracionModificada > B.getLimiteInferior() && duracionModificada <= B.getLimiteSuperior()) {
                                    for (FactorRiesgoMatrizCorrelacionMetrica F : B.getCollection()) {
                                        if (F.getNombre().toUpperCase().trim().equals(factor.getFactorRiesgoMatrizCorrelacion().getNombre().toUpperCase().trim())) {
                                            cambioesperadoTasa = F.getCambioEsperado();
                                            IDBanda = B.getId();
                                            break;
                                        }
                                    }
                                }
                                if (IDBanda != null) {
                                    break;
                                }
                            }
                            if (IDBanda != null) {
                                break;
                            }
                        }
                        if (IDBanda == null) {
                            throw new LogicaExcepcion("la duracion " + duracionModificada + " del producto " + productoPK + " no cae en ninguna banda");
                        }

                        cambioesperadoTasa /= 10000;
                        double var = valorpresente * duracionModificada * cambioesperadoTasa;
                        duracion = duracionModificada;

                        for (ZonaDTO Z : this.collection) {
                            for (BandasDTO B : Z.getBandas()) {
                                pstmt2.clearParameters();
                                if (IDBanda.equals(B.getId())) {
                                    pstmt2.setInt(1, Integer.valueOf(contrato.getPrimaryKey().toString()));
                                    pstmt2.setDouble(2, IDBanda.equals(B.getId()) ? valorpresente : 0);//0 para los demas
                                    pstmt2.setDouble(3, IDBanda.equals(B.getId()) ? duracion : 0);      //0 para los demas
                                    pstmt2.setDouble(4, IDBanda.equals(B.getId()) ? tir : 0);//0 para los demas
                                    pstmt2.setDouble(5, IDBanda.equals(B.getId()) ? cambioesperadoTasa : 0);//0 para los demas
                                    pstmt2.setDouble(6, IDBanda.equals(B.getId()) ? var : 0);//0 para los demas
                                    pstmt2.setString(7, factorMatriz);
                                    pstmt2.setInt(8, B.getId());
                                    pstmt2.executeUpdate();
                                }
                            }
                        }
                        //Determinando el riesgo de tasa de cambio
                        Moneda moneda = getMoneda(contrato.getMonedaPK());
                        MonedaPK monedaPK = (MonedaPK) moneda.getPrimaryKey();
                        if (!cambioesperadoMonedas.containsKey(monedaPK)) {
                            if (!relacionMonedasFactores.containsKey(monedaPK)) {
                                throw new LogicaExcepcion("Falta definir el factor de riesgo para la moneda " + monedaPK);
                            }
                            FactorRiesgoPersonalMetrica factorMoneda = (FactorRiesgoPersonalMetrica) relacionMonedasFactores.get(monedaPK);
                            double cambioesperadoMoneda = 0;
                            Double ValorMonedaVigente = moneda.obtenerValorVigenteA(fecha);
                            if (factorMoneda.getTipoCalculoCambioEsperado() == FactorRiesgoPersonal.CAMBIOESPERADO_FACTORMATRIZ) {
                                cambioesperadoMoneda = factorMoneda.getFactorRiesgoMatrizCorrelacion().getCambioEsperado() * ValorMonedaVigente;
                            } else {
                                cambioesperadoMoneda = moneda.cambioEsperadoValoresRegistrados(fecha, factorMoneda.getDefinidorCalculoCambioEsperado());
                                cambioesperadoMoneda = cambioesperadoMoneda * ValorMonedaVigente;
                            }
                            cambioesperadoMonedas.put(monedaPK, new Double(cambioesperadoMoneda));
                        }
//                        tasa.unsetEntityContext();
//                        moneda.unsetEntityContext();
                    }

//                    contrato.unsetEntityContext();
                } catch (Exception e) {
                    if (errores.containsKey(e)) {
                        errores.put(e.toString(), errores.get(e) + 1);
                    } else {
                        errores.put(e.toString(), Integer.valueOf("1"));
                    }
                }

            }
            Enumeration enume = errores.keys();
            while (enume.hasMoreElements()) {
                String msgError = enume.nextElement().toString();
                generarHTML.println(errores.get(msgError) + " errores de tipo " + msgError);
            }
            errores = new Hashtable<String, Integer>();
            productos.Finalizar();

            /*****************************************************************************************************
             * Para el caso de Posiciones de Especies el var se puede calcular con una factor tipo tasa
             * o un factor tipo precio.
             *****************************************************************************************************/


            _ctx = new InitialContext(prop);
            PosicionEspecieHome home2 = (PosicionEspecieHome) _ctx.lookup("ig.finanzas.PosicionEspecie");

            contratos = home2.findAll();
            i = contratos.iterator();
            generarHTML.println("Procesando :" + contratos.size() + " Contratos en PosicionEspecie");

//-------------
          do
            {
                if(!i.hasNext())
                    break;
                try
                {
                    PosicionEspecie posicion = (PosicionEspecie)i.next();
                    EspeciePK especiePK = posicion.getEspeciePK();
                    if(!relacionEspeciesFactores.containsKey(especiePK))
                        throw new LogicaExcepcion((new StringBuilder()).append("Falta definir el factor de riesgo para la especie ").append(especiePK.toString()).toString());
                    FactorRiesgoPersonalMetrica factor = (FactorRiesgoPersonalMetrica)relacionEspeciesFactores.get(especiePK);
                    if(factor.getTipo() == 0)
                    {
                        ///joooooo
                        double var = posicion.valorEnRiesgo(fecha, factor,false);
                        String factorMatriz = factor.getFactorRiesgoMatrizCorrelacion().getNombre();
                        double cambioesperado = 0.0D;
                        if(factor.getTipoCalculoCambioEsperado() == 0)
                            cambioesperado = factor.getFactorRiesgoMatrizCorrelacion().getCambioEsperado();
                        else
                            cambioesperado = posicion.cambioEsperadoValoresRegistrados(fecha, factor.getDefinidorCalculoCambioEsperado(),false);
                        pstmt1.setLong(1, ((ContratoPK)posicion.getPrimaryKey()).getIdInterna());
                        pstmt1.setDouble(2, Math.round(var * 100D) / 100L);
                        pstmt1.setString(3, factorMatriz);
                        pstmt1.setDouble(4, (double)Math.round(cambioesperado * 100000000D) / 100000000D);
                        pstmt1.executeUpdate();
                    } else
                    {
                        ManejadorFlujos flujosduracion = posicion.flujosParaDuracion(fecha);
                        TasaPK tasaPK = factor.getTasaPK();
                        if(tasaPK == null)
                            throw new DatoInvalidoExcepcion("El factor de riesgo asociado al producto no es del tipo tasa");
                        String factorMatriz = factor.getFactorRiesgoMatrizCorrelacion().getNombre();
                        Tasa tasa = null;
                        if(tasaPK.toString() != null && tasaPK.toString().trim().equals("TIPO_FACTORTASA_DESCUENTO")){
                            tasa = new TasaFactorDescuento("TIPO_FACTORTASA_DESCUENTO", "POSICIONESESPECIES", Long.valueOf( posicion.getPrimaryKey().toString()),true);
                        ((TasaFactorDescuento) tasa).setTipo(tasa.TIPO_SIMPLE);
                        }else {
                            tasa = getTasa(tasaPK);
                        }
                        ManejadorFlujos flujosintervalo = flujosduracion.flujosEntre(fecha, isFechaInicioCerrada(), new java.util.Date((new Long("9999999999999")).longValue()), true);
                        double valorpresente = flujosintervalo.valorDescontado(tasa, fecha);
                        double duracion = flujosintervalo.duracion(fecha, tasa);
                        double cambioesperadoTasa = 0.0D;
                        
                        flujosintervalo.adicionarFlujo(new Flujo(fecha, valorpresente * -1D, 0.0D, 0.0D, false, false));
                        double tir = flujosintervalo.tir();
                        Double duracionModificada = Double.valueOf(duracion / (1.0D + tir));
                        duracion = duracionModificada.doubleValue();
                        Integer IDBanda = null;
                       for (ZonaDTO Z : this.collection) {
                            for (BandasDTO B : Z.getBandas()) {
                                if (duracion == 0 && B.getNumero().equals(1)) {
                                    IDBanda = B.getId();
                                    break;
                                }
                                if (duracion > B.getLimiteInferior() && duracion <= B.getLimiteSuperior()) {
                                    for (FactorRiesgoMatrizCorrelacionMetrica F : B.getCollection()) {
                                        if (F.getNombre().toUpperCase().trim().equals(factor.getFactorRiesgoMatrizCorrelacion().getNombre().toUpperCase().trim())) {
                                            cambioesperadoTasa = F.getCambioEsperado();
                                            IDBanda = B.getId();
                                            break;
                                        }
                                    }
                                }
                                if (IDBanda != null) {
                                    break;
                                }
                            }
                            if (IDBanda != null) {
                                break;
                            }
                        }
                        if (IDBanda == null) {
                            throw new LogicaExcepcion("la duracion " + duracion + " no cae en ninguna banda");
                        }

                        cambioesperadoTasa /= 10000D;
                        double var = valorpresente * duracionModificada.doubleValue() * cambioesperadoTasa;
                        
                        //("INSERT INTO VARCONTRATOSTASA(IDCONTRATO, VALORPRESENTE, DURACION, TIR, CAMBIOESPERADO, VER, FACTORRIESGO, IDBANDA)
                        for (ZonaDTO Z : this.collection) {
                            for (BandasDTO B : Z.getBandas()) {
                                pstmt2.clearParameters();
                                pstmt2.setInt(1, Integer.valueOf(posicion.getPrimaryKey().toString()));//idcontrato
                                pstmt2.setDouble(2, IDBanda.equals(B.getId()) ? /*(double)*/ Math.round(valorpresente * 100) / 100 : 0);//valor presente
                                pstmt2.setDouble(3, IDBanda.equals(B.getId()) ? (double) (Math.round(duracion * 10000)) / 10000 : 0);//duracion
                                pstmt2.setDouble(4, IDBanda.equals(B.getId()) ? (double) (Math.round(tir * 100000000)) / 100000000 : 0);//tir
                                pstmt2.setDouble(5, IDBanda.equals(B.getId()) ? (double) (Math.round(cambioesperadoTasa * 100000000)) / 100000000 : 0);//cambioesperado
                                pstmt2.setDouble(6, IDBanda.equals(B.getId()) ? (double) Math.round(var * 100) / 100 : 0);//ver
                                pstmt2.setString(7, factorMatriz);//factorriesgo
                                pstmt2.setInt(8, B.getId());//idbanda
                                pstmt2.executeUpdate();
                            }
                        }

                    }
                    Moneda moneda = getMoneda(posicion.getMonedaPK());
                    MonedaPK monedaPK = (MonedaPK)moneda.getPrimaryKey();
                    if(!cambioesperadoMonedas.containsKey(monedaPK))
                    {
                        if(!relacionMonedasFactores.containsKey(monedaPK))
                            throw new LogicaExcepcion((new StringBuilder()).append("Falta definir el factor de riesgo para la moneda ").append(monedaPK).toString());
                        FactorRiesgoPersonalMetrica factorMoneda = (FactorRiesgoPersonalMetrica)relacionMonedasFactores.get(monedaPK);
                        double cambioesperadoMoneda = 0.0D;
                        if(factorMoneda.getTipoCalculoCambioEsperado() == 0)
                            cambioesperadoMoneda = factorMoneda.getFactorRiesgoMatrizCorrelacion().getCambioEsperado() * moneda.obtenerValorVigenteA(fecha);
                        else
                            cambioesperadoMoneda = moneda.cambioEsperadoValoresRegistrados(fecha, factorMoneda.getDefinidorCalculoCambioEsperado());
                        cambioesperadoMonedas.put(monedaPK, new Double(cambioesperadoMoneda));
                    }
                }
                catch(Exception e)
                {
                    e.printStackTrace();
                    if(errores.containsKey(e))
                        errores.put(e.toString(), Integer.valueOf(((Integer)errores.get(e)).intValue() + 1));
                    else
                        errores.put(e.toString(), Integer.valueOf("1"));
                }
            } while(true);

//-------------
            enume = errores.keys();
            while (enume.hasMoreElements()) {
                String msgError = enume.nextElement().toString();
                generarHTML.println(errores.get(msgError) + " errores de tipo " + msgError);
            }

            //---------------------------------------------------------------------------------------------------------

            i = cambioesperadoMonedas.keySet().iterator();

            while (i.hasNext()) {

                MonedaPK monedaPK = (MonedaPK) i.next();                
                pstmt3.setLong(1, monedaPK.getIdInterna());
                pstmt3.setDouble(2, ((Double) cambioesperadoMonedas.get(monedaPK)).doubleValue());
                pstmt3.executeUpdate();

            }
        } catch (RemoteException e) {
            e.printStackTrace();
            throw new DatoInvalidoExcepcion(e.toString());
        } finally {
            try {
                if (pstmt1 != null) {
                    pstmt1.close();
                }
            } catch (SQLException e) {
            }

            try {
                if (pstmt2 != null) {
                    pstmt2.close();
                }
            } catch (SQLException e) {
            }

            try {
                if (pstmt3 != null) {
                    pstmt3.close();
                }
            } catch (SQLException e) {
            }

            try {
                if (pstmt4_ != null) {
                    pstmt4_.close();
                }
            } catch (SQLException e) {
            }

            try {
                if (conn != null) {
                    conn.close();
                }
            } catch (SQLException e) {
            }
            if (productos != null) {
                productos.Finalizar();
            }
        }
    }

    public void setZonas(Collection<ZonaDTO> collection) {
        this.collection = collection;
    }

    public boolean isFechaInicioCerrada() {
        return fechaInicioCerrada;
    }

    public void setFechaInicioCerrada(boolean fechaInicioCerrada) {
        this.fechaInicioCerrada = fechaInicioCerrada;
    }

    private void _printHT(Hashtable ht, String name) {
        System.out.println("*******************");
        System.out.println("Name:" + name);
        Enumeration Key = ht.keys();
        while (Key.hasMoreElements()) {
            Object key = Key.nextElement();
            try {
                ig.metrica.riesgo.FactorRiesgoPersonalMetrica FACTOR = ((ig.metrica.riesgo.FactorRiesgoPersonalMetrica) ht.get(key));
                Byte TIPO = FACTOR.getTipo();
                String TASAPK = null;
                if (FACTOR.getTasaPK() != null) {
                    TASAPK = FACTOR.getTasaPK().toString();
                }
                Byte TIPO_CAL_ESP = FACTOR.getTipoCalculoCambioEsperado();
                String FACTOR_MATRIZ = FACTOR.getFactorRiesgoMatrizCorrelacion().getNombre();

                System.out.println(key.toString().trim() + "=TIPO:" + TIPO + ",TASAPK:" + TASAPK + ",TIPO_CAL_ESP:" + TIPO_CAL_ESP + ",FACTOR_MATRIZ:" + FACTOR_MATRIZ);
            } catch (Exception e) {
                String DATO = ((String) ht.get(key));
                System.out.println("DATO:" + DATO);
            }
        }
        System.out.println("*");
    }

    public void setFactores(Object get) {
        //throw new UnsupportedOperationException("Not supported yet.");
    }
}
